/***************************************************************************
 *   Copyright (C) 2009 by MJ   *
 *   hanfman_cool@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

//conf_server.cpp - is a part from steamserverutil by MJ
//steamserverutil.googlecode.com

//conf_server.cpp handles the functions to cinfigure a server

#include <iostream> //for cout and cin
#include <fstream> //for ifstream and ofstream
#include <stdlib.h> //for system()	
#include <string.h> //for strcpy, strcat and strcmp

#include "steamserverutil.h"
#include "mani.h"

//to make the differance of the arrays better 
#define OFF_N 0
#define OFF_C 1

using namespace std;


void copy_maps()
{
	
	//in char param[] is saved the complete cp command
	
	cout << "\n\nInto which server do you want to copy the maps?";

	if(!is_installed())
		return;


	

	unsigned short int choice;
	cout << " : ";
	cin >> choice;
	cin.ignore();

	installed=false; //is set true when server is installed

	
	strcpy(param, "cd ");
	strcat(param, workdir);
	strcat(param, "/");
	
	server_path(server[choice]);
	
	strcat(param, " && ");
	

	if(installed==true)
	{
		char temp[530];
		
		cout << "\n\nWhere are the maps? ";
		cin.getline(temp, 500);

		strcat(param, "&& cp -v ");
		strcat(param, temp);
		strcat(param, "/* maps/ ");

		system(param);
		
		//cin.ignore();

		
	}
	
}

void edit_mapcl(int x)
{
	//x=1 to edit maplist.txt
	//x=2 to edit mapcycle.txt
	//x=3 to edit votemaplist.txt (only with mani admin plugin)





	cout << "\n\nFrom which server do you want to edit the ";
	if(x==1)
		cout << "maplist?";
	if(x==2)
		cout << "mapcycle?";
	if(x==3)
		cout << "votemaplist.txt?";


	if(!is_installed())
		return;


	

	unsigned short int choice;
	cout << " : ";
	cin >> choice;
	cin.ignore();

	installed=false; //is set true when server is installed
	
	

	strcpy(param, workdir);
	strcat(param, "/");
	
	if(x==3)
		mani_test(server[choice]);
	else
		server_path(server[choice]);




	if(installed==true)
	{

		char mapfolder[70];


		
		strcpy(mapfolder, param);
		strcat(mapfolder, "/maps/");

		if (x==1)
		{
			strcat(param, "/maplist.txt");
	
		}
		if(x==2)
		{
			strcat(param, "/mapcycle.txt");
	
		}
		if(x==3)
		{
			strcat(param, "/cfg/mani_admin_plugin/votemaplist.txt");
		}







		bool exit =false;
			
		while(!exit)
		{
	
			if((x !=1) && (x !=2) && x !=3)
			{
				never_happen();
				break;
			}


			if (x==1)
			{
				cout << "\n\nHere is your current maplist: \n\n";
			}
			if(x==2)
			{
		
				cout << "\n\nHere is your current mapcycle: \n\n";
			}
			if(x==3)
			{
				cout << "\n\nHere is your current votemaplist: \n\n";
			}



	
			//x=1 to edit maplist.txt
			//x=2 to edit mapcycle.txt
			//x=3 to edit votemaplist.txt (only with mani admin plugin)

		
			
	
			ifstream input; //to read current *.txt
			input.open(param);

			ofstream output; //to add a new entry
			output.open(param, ios_base::app);


			char maps[350][50];
			unsigned int i;

			i=0;

			if(input.is_open())
			{	
				while(!input.eof())
				{
			
				
					input.getline(maps[i], 50);

					if(maps[i][0] == 10 || maps[i][0] == 0) //10 means new line, 0 means end of string
					{
						//nothing to do
					}
					else
					{
						cout << (i+1) << ".\t" << maps[i] << endl;
						i++;
					}
				}
			}
			else
			{
				cout << "\nNo maps. Please add one\n";
			
			}	
			input.close();





		
			unsigned short int choice;
			
			cout << "\n\n1. Add a map\n";
			cout << "2. Delete a map\n";
			cout << "3. Copy all maps from map folder\n";
			cout << "4. Delete all maps\n";
			cout << "5. Back \n";
			cout << " : ";

			cin >> choice;

			cin.ignore();


			

			char temp[200];
	
			switch(choice)
			{
				case 1: cout << "\n\nName of map? ";
				cin.getline(temp, 50);

				output << endl << temp;
				break;

				case 2: cout << "\n\nWhich map do you wish to delete? ";
				unsigned int choice;

				cin >> choice;
				choice--;
					
				if (choice >= i)
				{
					cout << "\n\nThis entry does not exist!\n";
				}
				else
				{
					ofstream save_del;
					save_del.open(param);

					for (int y = 0; y<i; y++)
					{
						if(y==choice)
						{
								//nothing to do
						}
						else
						{
							save_del << maps[y] << endl;
						}
					}
					save_del.close();
				}
				break;

				case 3: 
					char map[100];

					map[0]='^'; // to avoid errors with strncmp()
					map[1]=0;

					strcpy(temp, "ls -1 ");
					strcat(temp, mapfolder);
					strcat(temp, " > temp.txt");

					system(temp);

					
					{
						ifstream in_temp;
						in_temp.open("temp.txt");

						ofstream out;
						out.open(param);
						
						if(in_temp.is_open())
						{
							while(!in_temp.eof())
							{
								char temp[100];
								
								in_temp.getline(temp, 200);

								
								if(!strncmp(temp, map, strlen(map)))
								{
									continue;
								}

								if(!strcmp(temp, "materials"))
								{
									continue;
								}
					
								if(!strcmp(temp, "graphs"))
								{
									continue;
								}

								if(!strcmp(temp, "soundcache"))
								{
									continue;
								}



								for(int i=0; i <= strlen(temp); i++)
								{
									int k = 0;
									switch(temp[i])
									{
										case '.': k=1; 
										break;
										default: map[i]=temp[i];
										break;
									}
									if(k==1)
									{
										map[i]=0; //0 means end of string
										break;
									}
								}
								out << map << endl;
							}
						}
						else
						{
							never_happen();
							cout << "Cannot open temp.txt";
						}

						in_temp.close();
						out.close();
					}


					
					system("rm -rf temp.txt");

					break;

					
					case 4: char tempi;
					cout << "\n\nAll the maps are going to be deleted. Are you sure?(y|n) ";
					cin >> tempi;
				

					if(tempi=='y')
					{
						ofstream del_all;
						del_all.open(param);
						del_all.close();
					}
					break;
					case 5: exit=true;
					
					break;
				
					default: cout << "\n\nWrong choice. Try again ;)";
					break;
			}


			
			output.close(); //closing file to add a new entry
			
		}
	



	}



}



void config_servercfg()
{
	cout << "\n\nFrom which server do you wish to edit the server.cfg?\n";
	
	if(!is_installed())
		return;
	
	cout << " : ";
	unsigned int choice;
	cin >> choice;
	
	
	installed = false;
	
	strcpy(param, workdir); //using global array here
	strcat(param, "/");
	
	server_path(server[choice]);
	
	
	strcat(param, "cfg/server.cfg");
	
	
	
	if(installed)
	{
		bool exit = false;
	
		while(!exit)
		{
	
			ifstream in;
			in.open(param);
	
			char input[200][2][100]; //200 commands and 100 chars length
			int counter = 0;
	
			cout << "\n\nHere is your current server.cfg: \n\n\n";
	
			if(in.is_open())
			{
	
				while(!in.eof())
				{
					char temp[100];
					in.getline(temp, 100);
		
					switch(temp[0])
					{
						case '/': if(!strncmp(temp, "//n: ", 5))
						{
							strcpy(input[counter][OFF_N], &temp[5]);
							cout << (counter+1) << ".\t" << input[counter][OFF_N] << endl;
							//counter++;
						}
						break;
						default: strcpy(input[counter][OFF_C], temp);
							 counter ++;
						break;
			
					}
		
				}
		
		
			}
			else
				cout << "\n\nNo commands in server.cfg, please add one ;)\n\n";
	
			in.close();
	
			cout << "\n\n1. Add command\n";
			cout << "2. Delete a command\n";
			cout << "3. Delte the hole list\n";
			cout << "4. Exit\n";
			cout << " : ";
	
			cin >> choice;
			cin.ignore();
	
	
	
	
	
	
			switch(choice)
			{
		
				case 1: cout << "\n\nCommand: ";
				{
					char command[100];
					cin.getline(command, 100);
						
					cout << "Name of the command: ";
					char name[100];
					cin.getline(name, 100);
						
					ofstream out;
					out.open(param, ios_base::app);
				
					out << endl << "//n: " << name;
					out << endl << command;
				
					out.close();
				}
			
			
			
			
				break;
				case 2: cout << "\n\nWhich command do you want to delete?\n\n";
						
				cout << " : ";
				cin >> choice;
				
				choice--;


				if(choice > counter)
				{
					cout << "\n\nThis entry does not exist!";
				}
				else
				{

					ofstream save_del;
					save_del.open(param);




					for (int i = 0;i<counter;i++)
					{

								
						if(i==choice)
						{
								//nothing to do
						}
						else
						{
							save_del << "//n: " << input[i][OFF_N] << endl;
							save_del << input[i][OFF_C] << endl;
						}
								
					}
					save_del.close();
				}
				break;

				case 3: char temp;
				cout << "\n\nAll commands in server.cfg are going to be deleted. Are you sure?(y|n) ";
				cin >> temp;
				

				if(temp=='y')
				{
					ofstream del_all;
					del_all.open(param);
					del_all.close();
				}
				break;
				case 4: exit=true;
				break;
				default: cout << "\n\nTry again ;)\n";
			} 
	
		}
	
	}
	
	
}


void show_stats()
{
	cout << "\n\nFrom which server do you wish to see the stats?\n";
	
	if(!is_installed())
		return;
	
	
	
	cout << " : ";
	unsigned short int choice;
	cin >> choice;
	
	
	strcpy(param, workdir); //using global array here
	strcat(param, "/");
	server_path(server[choice]);	
	strcat(param, "stats.txt");
	cout << "\n\nHere are the current stats: \n\n\n";
	
	ifstream in;
	in.open(param);
	
	if(in.is_open())
	{
	
		while(!in.eof())
		{
			char temp[100];
			in.getline(temp, 100);
		
			cout << temp << endl;
		}
		
		
	}
	else
		cout << "\n\nOops there are no stats ;)\n\n";
				
	in.close();
				
	
				
	cout << "\n\nDelete all stats?(y|n) ";
	char asd;
	cin >> asd;
	
	if(asd=='y')
	{
		cout << "Are you sure, really delete all stats?(y|n) ";
		cin >> asd;
		
		if(asd=='y')
		{
			ofstream delete_;
			delete_.open(param);
			delete_.close();
			cout << "\n\nDeleted succesfully!!\n\n";
		}
		
		
	}
}

void get_servername(unsigned int choice)
{
	switch(choice)
	{
		case 1: strcpy(param, "css");
			break;
		case 2: strcpy(param, "dods");
			break;
		case 3: strcpy(param, "garrysmod");
			break;
		case 4: strcpy(param, "hl2mp");
			break;
		case 5: strcpy(param, "tf");
			break;
		case 6: strcpy(param, "cstrike");
			break;
		case 7: strcpy(param, "cscz");
			break;
		case 8: strcpy(param, "dmc");
			break;
		case 9: strcpy(param, "dod");
			break;
		case 10: strcpy(param, "gearbox");
			break;
		case 11: strcpy(param, "ricochet");
			break;
		case 12: strcpy(param, "tfc");
			break;
		case 13: strcpy(param, "darkmessiah");
			break;
		case 14: strcpy(param, "chivalry");
			break;
		case 15: strcpy(param, "diprip");
			break;
		case 16: strcpy(param, "insurgency");
			break;
		case 17: strcpy(param, "synergy");
			break;
		case 18: strcpy(param, "zps");
			break;
		case 19: strcpy(param, "esmod");
			break;
		case 20: strcpy(param, "l4d");
			break;
		case 21: strcpy(param, "hole");
			break;
	}
}

void set_workspace()
{
	cout << "\n\nCurrent workspace is: " << workdir;
	
	cout << "\nAvailable workspaces: ";
	
	strcpy(param, getenv("HOME"));
	strcat(param, "/.steamserverutil/workdirs");
	
	ifstream in(param);
	
	char work[10][200];
	unsigned short int counter;
	
	bool exit = false;
			
	while(!exit)
	
	{
		if(in.is_open())
		{
			while(!in.eof())
			{
				cin.getline(work[counter], 200);
				cout << (counter+1) << ".\t" << work[counter];
				
				if(counter == 10)
				{
					never_happen();
					cout << "\nFatal Error: Too many workspaces!\n";
				}
			}
			
			
		}
		else
			cout << "\nThere are no workspaces! Add one!\n";
		
		
		in.close();
		
		unsigned short int choice;
		
		cout << "\n\n1. Add workspace\n";
		cout << "2. Delete workspace\n";
		cout << "3. Delete all workspaces\n";
		cout << "4. Set the current standard workspace\n";
		cout << "5. Exit\n";
		cout << " : ";
		cin >> choice;
		cin.ignore();
		
		switch (choice)
		{
			case 1: cout << "\nPath: ";
				{
					char temp[200];
					cin.getline(temp, 200);
					ofstream out;
					out.open(param, ios_base::app);
					out << endl << temp;
					out.close();
				}
				break;
		
		
			case 2: cout << "\n\nWhich workspace do you want do delete? ";
				cin >> choice;
				
				choice--;
			
				if(choice >= counter)
				{
					cout << "\nThis entry does not exist!\n\n";
				}
				else
				{
			
					ofstream save_del;
					save_del.open(param);
			
			
			
			
					for (int i = 0;i<counter;i++)
					{
			
								
						if(i==choice)
						{
										//nothing to do
						}
						else
						{
							save_del << endl << work[i];
						}
									
					}
					save_del.close();
				}
				break;
			case 3: char temp;
				cout << "\n\nAll workspaces are going to be deleted. Are you sure?(y|n) ";
				cin >> temp;
							
			
				if(temp=='y')
				{
					ofstream del_all;
					del_all.open(param);
					del_all.close();
				}
				break;
			case 4:
				cout << "\n\nWhich workspace do you want to set as the current wokspace? ";
				cin >> choice;
			
				choice--;
		
				if(choice >= counter)
				{
					cout << "\nThis entry does not exist!\n\n";
				}
				else
				{
					cout << "Setting \"" << work[choice] << "\" to standard..";
					
					//extra variable is needed here
					char params[200];
					strcpy(params, getenv("HOME"));
					strcat(params, "/.steamserverutil/workdir");
					
					ofstream save(params);
					save << work[choice];
					save.close();
					
					cout << "\n\nPlease restart steamserverutil now, to make the changes effect!\n\n";
				}
				
				
				break;
			case 5: exit=true;
				break;
			default: cout << "\n\nTry again;)\n\n";
			break;
		}
	}
}


void backup()
{
	cout << "\n\nWhich server do you wish to backup?\n";
	
	is_installed();
	cout << ++i << "\tHole content\n";
	cout << " : ";
	unsigned short int choice;
	cin >> choice;
	
	get_servername(server[choice]);
	
	//getting name of server...
	char name[10];
	strcpy(name, param);
	
	//writing the temporary file, needed to recognize the archive
	strcpy(param, workdir);
	strcat(param, "/ssu_cur_servername.txt");
	
	ofstream out_name(param);
	
	out_name << name << endl;	
	out_name << "# steamserverutil " << _version << endl;
	out_name << "# This tar archive is a backup file of steamserverutil (steamserverutil.googlecode.com)\n";
	out_name << "# Please do not make any changes on this archive and file!\n";
	out_name.close();
	
	
	strcpy(param, "cd ");
	strcat(param, workdir);
	strcat(param, " && tar -cf ../backup_steamserverutil_");
	strcat(param, name);
	strcat(param, ".tar ssu_cur_servername.txt ");
	
	if(server[choice] != 21)
		server_path(server[choice]);
	else
		strcat(param, "servers_source/ servers_hl1/ installed_servers hldpsupdatetool.bin steam favorites ");
	
	
	
	cout << "Creating backup_steamserverutil.tar... ";
	cout << flush;
	
	system(param);
	
	i--;
	
	cout << "Success\n";
	
	
}

void restore_backup()
{
	cout << "\nWhere is the backup file (*.tar)? ";
	
	bool valid;
	char path[500];
	cin.ignore();
	cin.getline(path, 500);
	
	strcpy(param, "tar --list ");
	strcat(param, path);
	strcat(param, " > temp.txt");
	
	ifstream in(param);
	
	while(!in.eof())
	{
		
		char temp[50];
		in.getline(temp, 50);
		if(!strcmp(temp, "ssu_cur_servername.txt"))
		{
			valid = true;
			break;
		}
	}
	
	in.close();
	
	system("rm -rf temp.txt");
	
	if(!valid)
	{
		cout << "\n\nThis seems not to be a valid backup file!\nAborting...\n\n";
		return;
	}
	
	
	
	strcpy(param, "cd ");
	strcat(param, workdir);
	strcat(param, " && tar -xf ");
	strcat(param, path);
	
	cout << "Extracting archive...\n";
	cout << flush;
	system(param);
	
	
	cout << "\nAdding restored server to installed_servers file\n";
	
	strcpy(param, workdir);
	strcat(param, "/installed_servers");
	
	//using path[] to open ssu_cur_servername.txt now
	
	strcpy(path, workdir);
	strcat(path, "/ssu_cur_servername.txt");
	
	
	in.open(path);
	ofstream out(param, ios_base::app);
	
	while(!in.eof())
	{
		char temp[50];
		
		if(temp[0] == '#')
			break;
		
		out << path;
	}
	
	in.close();
	out.close();
	
	cout << "\nSuccess!\n\n";
}


//here you can configure servers
void config_server()
{
	bool exit=false;

	while(!exit)
	{
		unsigned short int choice;
		cout << "\n\n1. Copy maps into server\n";
		cout << "2. Edit maplist\n";
		cout << "3. Edit mapcylce\n";
		cout << "4. Edit server.cfg\n";
		cout << "5. Show stats\n";
		cout << "6. Configure mani admin plugin\n";
		cout << "7. Change workspace(s)\n";
		cout << "8. Backup\n";
		cout << "9. Restore a Backup\n";
		cout << "10. Exit to main menu\n";
		cout << " : ";
		cin  >> choice;	

		switch(choice)
		{
			case 1: copy_maps();
			break;
			case 2: edit_mapcl(1); //1 means edit maplist.txt
			break;
			case 3: edit_mapcl(2); //2 means edit mapcycle.txt
			break;
			case 4: config_servercfg();
			break;
			case 5: show_stats();
			break;
			case 6:	config_mani();
			break;
			case 7: set_workspace();
			break;
			case 8: backup();
			break;
			case 9: restore_backup();
			break;
			case 10: exit=true;
			break;
			default: cout << "\n\nWrong choice. Try again;)";
			break;
		}
	}
}
